package ddz.logic;

import com.kaka.notice.Facade;
import com.kaka.notice.FacadeFactory;
import ddz.db.entity.ItemInfo;
import ddz.db.entity.UserInfo;
import ddz.numerical.manager.ConfItemInfoManager;
import ddz.numerical.pojo.ConfItemInfo;
import ddz.protos.ModuleItem;
import ddz.utils.JsonUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ItemUtils {

    /**
     * 是否拥有指定数量的道具物品，仅限道具
     *
     * @param items 玩家道具列表
     * @param cid   道具配置ID
     * @param num   指定数量
     * @return true数量足够
     */
    public static final boolean hasPropItem(List<ItemInfo> items, int cid, int num) {
        Facade facade = FacadeFactory.getFacade();
        ConfItemInfoManager confItemInfoManager = facade.retrieveProxy(ConfItemInfoManager.class);
        ConfItemInfo confItemInfo = confItemInfoManager.getConfItemInfo(cid);
        if (confItemInfo.getPileup() == 0) {
            int count = 0;
            for (ItemInfo itemInfo : items) {
                if (itemInfo.getCid() == cid) {
                    count += itemInfo.getNum();
                    if (count >= num) return true;
                }
            }
        } else {
            for (ItemInfo itemInfo : items) {
                if (itemInfo.getCid() == cid) {
                    if (itemInfo.getNum() >= num) return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取道具物品数量，仅限道具
     *
     * @param items 玩家道具列表
     * @param cid   道具配置ID
     * @return 道具数量
     */
    public static final int getPropItemAmount(List<ItemInfo> items, int cid) {
        int count = 0;
        for (ItemInfo itemInfo : items) {
            if (itemInfo.getCid() == cid) {
                count += itemInfo.getNum();
            }
        }
        return count;
    }

    /**
     * 从玩家数据中解析出道具列表
     *
     * @param items 道具列表字符串表示形式
     * @return 道具列表
     */
    public static final List<ItemInfo> parseItemList(String items) {
        if (items == null || "".equals(items)) {
            return new ArrayList<>(0);
        }
        return (ArrayList<ItemInfo>) JsonUtils.toCollection(items, ArrayList.class, ItemInfo.class);
    }

    /**
     * 过滤删除道具 </br>
     * 删除数量为0和已过期的记牌器 </br>
     *
     * @param itemInfoList 道具列表
     * @return true表示有变化，需要更新
     */
    public static final boolean filterItems(List<ItemInfo> itemInfoList) {
        boolean flag = false;
        int i = 0, max = itemInfoList.size();
        while (i < max) {
            ItemInfo info = itemInfoList.get(i);
            if (info.getNum() <= 0) {
                itemInfoList.remove(i);
                max--;
                flag = true;
                continue;
            }
            if (info.getCid() > 700 && info.getCid() % 100 == 1) {
                int day = info.getCid() % 700;
                long startTime = info.getTimestamp();
                long endTime = startTime + day * 86400000;
                long remaingTime = endTime - System.currentTimeMillis();
                if (remaingTime <= 0) {
                    itemInfoList.remove(i);
                    max--;
                    flag = true;
                    continue;
                }
            }
            i++;
        }
        return flag;
    }

    /**
     * 删除道具物品
     *
     * @param itemList 玩家道具列表
     * @param cid      删除的道具配置ID
     * @param num      删除的数量
     * @return true删除成功
     */
    public static final boolean delItem(List<ItemInfo> itemList, int cid, int num, UserInfo userInfo) {
        if (cid == 1) {
            if (num <= 0) return false;
            userInfo.setGold(userInfo.getGold() - num);
            if (userInfo.getGold() < 0) {
                userInfo.setGold(0);
            }
            return true;
        } else if (cid == 2) {
            if (num <= 0) return false;
            userInfo.setDiam(userInfo.getDiam() - num);
            if (userInfo.getDiam() < 0) {
                userInfo.setDiam(0);
            }
            return true;
        } else if (cid == 3) {
            if (num <= 0) return false;
            userInfo.setFuka(userInfo.getFuka() - num);
            if (userInfo.getFuka() < 0) {
                userInfo.setFuka(0);
            }
            return true;
        }
        if (itemList == null) return true;
        Facade facade = FacadeFactory.getFacade();
        ConfItemInfoManager confItemInfoManager = facade.retrieveProxy(ConfItemInfoManager.class);
        ConfItemInfo confItemInfo = confItemInfoManager.getConfItemInfo(cid);
        if (confItemInfo.getPileup() == 0) { //不可叠加
            if (num < 0) {
                //全部清除
                int i = 0, max = itemList.size();
                while (i < max) {
                    ItemInfo itemInfo = itemList.get(i);
                    if (itemInfo.getCid() == cid) {
                        itemList.remove(i);
                        max--;
                        continue;
                    }
                    i++;
                }
                return true;
            } else {
                int count = 0;
                for (ItemInfo info : itemList) {
                    if (info.getCid() == cid) {
                        count++;
                    }
                }
                if (count >= num) {
                    count = 0;
                    int i = 0, max = itemList.size();
                    while (i < max) {
                        ItemInfo itemInfo = itemList.get(i);
                        if (itemInfo.getCid() == cid) {
                            itemList.remove(i);
                            max--;
                            count++;
                            if (count >= num) break;
                            continue;
                        }
                        i++;
                    }
                    return true;
                }
            }
        } else { //可叠加的物品
            int size = itemList.size();
            int idx = -1;
            for (int i = 0; i < size; i++) {
                ItemInfo info = itemList.get(i);
                if (info.getCid() == cid) {
                    idx = i;
                    break;
                }
            }
            if (idx >= 0) {
                ItemInfo itemInfo = itemList.get(idx);
                if (num < 0) {
                    //全部清除
                    itemInfo.setNum(0);
                } else {
                    itemInfo.setNum(itemInfo.getNum() - num);
                }
                if (itemInfo.getNum() <= 0) itemList.remove(idx);
                return true;
            }
        }
        return false;
    }

    /**
     * 处理虚拟货币（游戏豆、钻石、福卡）
     *
     * @param addedList 使用addItem方法添加物品后新添加的物品
     */
    public static final void processVirtualCurrency(List<ItemInfo> addedList, UserInfo userInfo) {
        for (ItemInfo itemInfo : addedList) {
            if (itemInfo.getCid() == 1) {
                userInfo.setGold(userInfo.getGold() + itemInfo.getNum());
            } else if (itemInfo.getCid() == 2) {
                userInfo.setDiam(userInfo.getDiam() + itemInfo.getNum());
            } else if (itemInfo.getCid() == 3) {
                userInfo.setFuka(userInfo.getFuka() + itemInfo.getNum());
            }
        }
    }

    /**
     * 添加道具物品
     *
     * @param itemList  玩家道具列表
     * @param cid       添加的道具配置ID
     * @param num       添加额数量
     * @param addedList 新增的道具
     * @return 玩家道具列表
     */
    public static final List<ItemInfo> addItem(List<ItemInfo> itemList, int cid, int num, List<ItemInfo> addedList) {
        if (itemList == null) return null;
        if (cid == 1 || cid == 2 || cid == 3) {
            if (num > 0) {
                if (addedList != null) addedList.add(new ItemInfo(cid, num));
            }
            return itemList;
        }
        Facade facade = FacadeFactory.getFacade();
        ConfItemInfoManager confItemInfoManager = facade.retrieveProxy(ConfItemInfoManager.class);
        ConfItemInfo confItemInfo = confItemInfoManager.getConfItemInfo(cid);
        if (confItemInfo.getPileup() == 0) {
            //不可叠加
            if (confItemInfo.getId() > 700 && confItemInfo.getId() % 100 == 7) {
                //时间限制的记牌器
                for (int i = 0; i < num; i++) {
                    ItemInfo itemInfo = new ItemInfo(cid, 1, System.currentTimeMillis());
                    itemList.add(itemInfo);
                    if (addedList != null) addedList.add(itemInfo);
                }
            } else {
                ItemInfo itemInfo = new ItemInfo(cid, 1);
                for (int i = 0; i < num; i++) {
                    itemList.add(itemInfo);
                    if (addedList != null) addedList.add(itemInfo);
                }
            }
        } else {
            //可叠加的物品
            ItemInfo itemInfo = null;
            for (ItemInfo info : itemList) {
                if (info.getCid() == cid) {
                    itemInfo = info;
                    break;
                }
            }
            if (itemInfo == null) {
                ItemInfo info = new ItemInfo(cid, num);
                itemList.add(info);
                if (addedList != null) addedList.add(info);
            } else {
                itemInfo.setNum(itemInfo.getNum() + num);
                if (addedList != null) addedList.add(new ItemInfo(cid, num));
            }
        }
        return itemList;
    }

    public static void buildProtoItem(List<ItemInfo> addedItemList, Consumer<ModuleItem.Item> consumer) {
        ModuleItem.Item.Builder itemBuilder = ModuleItem.Item.newBuilder();
        for (ItemInfo info : addedItemList) { //遍历新增道具列表
            itemBuilder.setCid(info.getCid());
            itemBuilder.setNum(info.getNum());
            if (info.getCid() > 700 && info.getCid() % 100 == 7) {
                int day = info.getCid() % 700;
                long startTime = info.getTimestamp();
                long endTime = startTime + day * 86400000;
                long remaingTime = endTime - System.currentTimeMillis();
                itemBuilder.setRemainingTime(remaingTime);
            }
            consumer.accept(itemBuilder.build());
            itemBuilder.clear();
        }
    }

}
